package cn.community.system.web.controller;

import cn.community.system.domain.Association;
import cn.community.system.domain.Member;
import cn.community.system.exception.LogicException;
import cn.community.system.service.IAdminService;
import cn.community.system.service.IAssociationService;
import cn.community.system.service.IMemberService;
import cn.community.system.shiro.UserToken;
import cn.community.system.shiro.LoginType;
import cn.community.system.util.Const;
import cn.community.system.util.JsonResult;
import cn.community.system.util.UserContext;
import cn.community.system.util.VerifyCode;
import org.apache.ibatis.logging.LogException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("users")
public class UserInfoController {

    @Autowired
    private IAssociationService associationService;

    @Autowired
    private IMemberService memberService;

    // 社团注册
    @PostMapping("/associationRegist")
    @ResponseBody
    public Object associationRegist(Association association, String rpassword) {
        associationService.regist(association, rpassword);
        return JsonResult.success();
    }

    // 社团成员注册
    @RequestMapping("/memberRegist")
    @ResponseBody
    public Object memberRegist(Member member, String rpassword) {
        memberService.regist(member, rpassword);
        return JsonResult.success();
    }

    // 验证码
    @RequestMapping("/randomCode")
    @ResponseBody
    public void randomCode(HttpServletRequest req, HttpServletResponse resp) {
        VerifyCode code = new VerifyCode();
        code.VerifyCode(req, resp);
        System.out.println("验证码：" + req.getSession().getAttribute(Const.RANDOMCODE_IN_SESSION));
    }

    // 超管登录
    private static final String ADMIN_LOGIN_TYPE = LoginType.ADMIN.toString();

    @PostMapping("/adminLogin")
    @ResponseBody
    public JsonResult adminLogin(String number, @RequestParam("username") String username, @RequestParam("password") String password, String randomCode, HttpServletRequest req, String url) {
        url = "/activity/admin/list";
        return this.login(number,username, password, randomCode, ADMIN_LOGIN_TYPE, req, url);
    }

    // 社团登录
    private static final String ASSOCIATION_LOGIN_TYPE = LoginType.ASSOCIATION.toString();

    @PostMapping("/associationLogin")
    @ResponseBody
    public JsonResult associationLogin(String number, @RequestParam("username") String username, @RequestParam("password") String password, String randomCode, HttpServletRequest req, String url) {
        url = "/activity/association/list";
        return this.login(number,username, password, randomCode, ASSOCIATION_LOGIN_TYPE, req, url);
    }

    // 社团成员登录
    private static final String MEMBER_LOGIN_TYPE = LoginType.MEMBER.toString();

    @PostMapping("/memberLogin")
    @ResponseBody
    public JsonResult memberLogin(@RequestParam("number") String number, @RequestParam("username")String username, @RequestParam("password") String password, String randomCode, HttpServletRequest req, String url) {
        url = "/activity/member/list";
        return this.login(username,number, password, randomCode, MEMBER_LOGIN_TYPE, req, url);
    }

    private JsonResult login(String number,String username, String password, String randomCode, String loginType, HttpServletRequest req, String url) {
        // 必须先判断验证码 是否一致 ，如果一致然后才往下进行
        // 如果session中没有验证码,告知验证码错误
        String randomCodeInSession = (String) req.getSession().getAttribute(Const.RANDOMCODE_IN_SESSION);
        try {
            if (null == randomCodeInSession || randomCodeInSession.equals("")) {
                System.out.println("验证码错误！");
                return JsonResult.error(JsonResult.CODE_ERROR_RANDOMCODE,JsonResult.MSG_RANDOMCODE,null);
            }
            // 如果用户没有提交验证码，告知验证码错误
            if (null == randomCode || randomCode.equals("")) {
                System.out.println("验证码错误！");
                return JsonResult.error(JsonResult.CODE_ERROR_RANDOMCODE,JsonResult.MSG_RANDOMCODE,null);
            }
            // 如果session中的验证码和用户提交的验证码不一致，告知验证码错误
            if (!randomCode.equals(randomCodeInSession)) {
                System.out.println("验证码错误！");
                return JsonResult.error(JsonResult.CODE_ERROR_RANDOMCODE,JsonResult.MSG_RANDOMCODE,null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }

        // 获取当前登录对象
        Subject currentUser = SecurityUtils.getSubject();
        // 判断该用户是否已经验证
        if (!currentUser.isAuthenticated()) {
            // 没有验证，生成该用户的token凭证
            UserToken userToken = new UserToken(username, password, loginType);
            userToken.setRememberMe(false);
            try {
                // 验证用户身份
                currentUser.login(userToken);
                if(loginType == ADMIN_LOGIN_TYPE){  // 超管
                    if(!UserContext.getCurrentAdmin().getNumber().equals(number)){
                        throw new LogicException("用户不存在！");
                    }
                }else if (loginType == ASSOCIATION_LOGIN_TYPE){  // 社团
                    if(!UserContext.getCurrentAssociation().getNumber().equals(number)){
                        throw new LogicException("用户不存在！");
                    }
                }else if(loginType == MEMBER_LOGIN_TYPE){  // 社团成员
                    if(!UserContext.getCurrentMember().getUsername().equals(number)){
                        throw new LogicException("用户不存在！");
                    }
                }
            }
            catch(IncorrectCredentialsException ice){
                System.out.println("用户名/密码不匹配！");
                return JsonResult.error(JsonResult.CODE_ERROR_INCORRECT,JsonResult.MSG_INCORRECT,null);
            } catch(LockedAccountException lae){
                System.out.println("账户已被冻结！");
                return JsonResult.error(JsonResult.CODE_ERROR_LOCKED,JsonResult.MSG_LOCKED,null);
            } catch(AuthenticationException ae){
                return JsonResult.error(JsonResult.CODE_ERROR_INCORRECT,JsonResult.MSG_INCORRECT,null);
            }
        }
        return JsonResult.success(url);
    }
}
